package com.linkmcn.uaa.config;

import com.linkmcn.security.config.IgnoreUrlPropsConfig;
import com.linkmcn.security.handle.MateAuthenticationFailureHandler;
import com.linkmcn.security.handle.MateAuthenticationSuccessHandler;
import com.linkmcn.uaa.service.impl.UserDetailsServiceImpl;
import com.linkmcn.uaa.sms.SmsCodeAuthenticationSecurityConfig;
import com.linkmcn.uaa.social.SocialAuthenticationSecurityConfig;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import javax.annotation.Resource;

/**
 * 安全配置中心
 *
 **/
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {


//	@Autowired
//	private IgnoreUrlPropsConfig ignoreUrlPropsConfig;


//	public static void main(String[] args) {
//		String webApp = new BCryptPasswordEncoder().encode("webApp");
//		System.out.println(webApp);
//
//	}

	@Bean
	public PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}

	@Resource
	private SmsCodeAuthenticationSecurityConfig smsCodeAuthenticationSecurityConfig;

	@Resource
	private SocialAuthenticationSecurityConfig socialAuthenticationSecurityConfig;

	/**
	 * 必须要定义，否则不支持grant_type=password模式
	 *
	 * @return AuthenticationManager
	 */
	@Bean
	@Override
	@SneakyThrows
	public AuthenticationManager authenticationManagerBean() {
		return super.authenticationManagerBean();
	}

	@Bean
	public AuthenticationSuccessHandler mateAuthenticationSuccessHandler() {
		return new MateAuthenticationSuccessHandler();
	}

	@Bean
	public AuthenticationFailureHandler mateAuthenticationFailureHandler() {
		return new MateAuthenticationFailureHandler();
	}


	@Override
	@Bean
	public UserDetailsService userDetailsService() {
		return new UserDetailsServiceImpl();
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry config
				= http.requestMatchers().anyRequest()
				.and()
				.apply(smsCodeAuthenticationSecurityConfig)
				.and()
				.apply(socialAuthenticationSecurityConfig)
				.and()
				.authorizeRequests();
//		ignoreUrlPropsConfig.getUrls().forEach(e -> {
//			config.antMatchers(e).permitAll();
//		});
		config

				/**
				 *  .antMatchers("/api/public/**").permitAll()
				 *                 .antMatchers("/api/register").permitAll()
				 *                 .antMatchers("/api/activate").permitAll()
				 *                 .antMatchers("/api/authenticate").permitAll()
				 *                 .antMatchers("/api/account/reset-password/init").permitAll()
				 *                 .antMatchers("/api/account/reset-password/finish").permitAll()
				 *                 .antMatchers("/api/**").authenticated()
				 *                 .antMatchers("/management/health").permitAll()
				 *                 .antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
				 *                 .antMatchers("/v2/api-docs/**").permitAll()
				 *                 .antMatchers("/swagger-resources/configuration/ui").permitAll()
				 *                 .antMatchers("/swagger-ui/index.html").hasAuthority(AuthoritiesConstants.ADMIN)
				 */
				.antMatchers("/auth/**").permitAll()
				.antMatchers("/oauth/**").permitAll()
				.antMatchers("/actuator/**").permitAll()
				.antMatchers("/v2/api-docs").permitAll()
				.antMatchers("/v2/api-docs-ext").permitAll()
				.anyRequest().authenticated()
				.and()
				.csrf().disable();
	}

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.
				userDetailsService(userDetailsService())
				.passwordEncoder(passwordEncoder());
	}
}
